package com.bjzs.es.study.dao;

import com.bjzs.es.study.domain.DolphinProcessInstanceTest;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateResponse;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class DolphinProcessInstanceTestDao {

    @Resource
    private ElasticsearchRestTemplate elasticsearchTemplate;

    public void save(DolphinProcessInstanceTest instance) {
        elasticsearchTemplate.save(instance);
    }

    public DolphinProcessInstanceTest getByRid(Long rid) {
        Criteria criteria = Criteria.where("rid").is(rid);
        CriteriaQuery query = new CriteriaQuery(criteria);
        SearchHit<DolphinProcessInstanceTest> result =
            elasticsearchTemplate.searchOne(query, DolphinProcessInstanceTest.class);
        return result == null ? null : result.getContent();
    }

    public UpdateResponse update(DolphinProcessInstanceTest instance) {
        IndexCoordinates IndexCoordinates =
            elasticsearchTemplate.getIndexCoordinatesFor(DolphinProcessInstanceTest.class);
        UpdateQuery updateQuery = UpdateQuery.builder(instance.getId())
            .withDocument(buildDocument(instance))
            .build();
        UpdateResponse update = elasticsearchTemplate.update(updateQuery, IndexCoordinates);
        return update;
    }

    public  SearchHits<DolphinProcessInstanceTest> searchByPage(Long projectCode, String name,
        Integer executorId, String hostName, Integer state, Long startTime, Long endTime,
        Integer isSubProcess, int page, int number) {
        Criteria criteria = Criteria.where("project_code").is(projectCode)
            .and(Criteria.where("name").startsWith(name))
            .and(Criteria.where("executor_id").is(executorId))
            .and(Criteria.where("host_name").is(hostName))
            .and(Criteria.where("state").is(state))
            .and(Criteria.where("is_sub_process").is(isSubProcess))
            .and(Criteria.where("start_time").between(startTime, endTime));
        CriteriaQuery query = new CriteriaQuery(criteria, PageRequest.of(page, number));
        query.addSort(Sort.by(Sort.Direction.DESC, "start_time"));
        SearchHits<DolphinProcessInstanceTest> search =
            elasticsearchTemplate.search(query, DolphinProcessInstanceTest.class);
        return search;
    }

    private Document buildDocument(DolphinProcessInstanceTest instance) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", instance.getId());
        map.put("rid", instance.getRid());
        map.put("project_code", instance.getProjectCode());
        map.put("name", instance.getName());
        map.put("executor_id", instance.getExecutorId());
        map.put("host_name", instance.getHostName());
        map.put("state", instance.getState());
        map.put("start_time", instance.getStartTime());
        map.put("is_sub_process", instance.getIsSubProcess());
        return Document.from(map);
    }

    public SearchHits<DolphinProcessInstanceTest> searchAll() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
            .withQuery(QueryBuilders.matchAllQuery())
            .build();
        SearchHits<DolphinProcessInstanceTest> search = elasticsearchTemplate.search(nativeSearchQuery, DolphinProcessInstanceTest.class);
        return search;
    }

    public void delete(List<String> ids) {
        Criteria criteria = Criteria.where("id").in(ids);
        CriteriaQuery query = new CriteriaQuery(criteria);
        elasticsearchTemplate.delete(query, DolphinProcessInstanceTest.class, elasticsearchTemplate.getIndexCoordinatesFor(DolphinProcessInstanceTest.class));
    }


}
